﻿/*****************************************************************************
 
 Use of Ext is under the Ext JS license, for more information, 
 please visit http://extjs.com/products/license.php page. 
  
 You should confirm that you have read, understood and accept ethical criteria listed. 
 If not, see <http://www.mvcnext.com/license/>.
  
 Version: 1.0.0.0
 Website: http://www.mvcnext.com/
 
 Copyright (c) Yoganand R. All rights reserved.
 For continued development and updates, visit http://yogsbreath.net
 
 ******************************************************************************/
using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Web.UI;
using System.Text;

namespace MVCnExt.Web.UI.Ext
{
    public abstract class Store : ExtConfig
    {
        private List<ScriptReference> _references = new List<ScriptReference>();

        private List<SortInfo> _sortInfo = new List<SortInfo>();

        public override IList<ScriptDescriptor> GetScriptDescriptors()
        {
            IList<ScriptDescriptor> list = base.GetScriptDescriptors();

            if (list.Count == 0)
                list.Add(new ExtScriptControlDescriptor("Ext.data.Store", "ctl00"));

            ScriptControlDescriptorBase desc = (ScriptControlDescriptorBase)list[0];

            desc.Type = "Ext.data.Store";

            String[] properties = new String[]{
                "autoLoad", "pruneModifiedRecords", "remoteSort"
            };

            Type component = typeof(Store);

            foreach (String property in properties)
            {
                PropertyInfo i = component.GetProperty(property);

                if (i == null)
                    throw new InvalidOperationException(String.Format("Property not found, 'ExtStore.{0}'", property));

                Object value = i.GetValue(this, null);

                if (value == null)
                {
                    continue;
                }

                if (!(value is String))
                    desc.AddPropertyBase(property, value);
                else
                    desc.AddPropertyBase(property, String.Format("'{0}'", value));
            }
            //add items
            if (proxy != null && proxy.Count != 0)
            {
                // build items list
                StringBuilder tabList = new StringBuilder("");

                for (int i = 0; i < proxy.Count; i++)
                {
                    // add comma between items
                    if (i != 0)
                    {
                        tabList.Append(",");
#if DEBUG
                        tabList.AppendLine("\t\t\t");
#endif
                    }

                    // get the item script
                    IList<ScriptDescriptor> descriptors = proxy[i].GetScriptDescriptors();

                    // write the item's config to the list
                    tabList.Append(((ExtScriptControlDescriptor)descriptors[0]).WriteScript(ScriptType.NewOnly));
                }

                tabList.Append("");

                desc.AddPropertyBase("proxy", tabList);
            }

            //add reader
            if (reader != null && reader.Count != 0)
            {
                // build items list
                StringBuilder tabList = new StringBuilder("");

                for (int i = 0; i < reader.Count; i++)
                {
                    // add comma between items
                    if (i != 0)
                    {
                        tabList.Append(",");
#if DEBUG
                        tabList.AppendLine("\t\t\t");
#endif
                    }

                    // get the item script
                    IList<ScriptDescriptor> descriptors = reader[i].GetScriptDescriptors();

                    // write the item's config to the list
                    tabList.Append(((ExtScriptControlDescriptor)descriptors[0]).WriteScript(ScriptType.NewOnly));
                }

                tabList.Append("");

                desc.AddPropertyBase("reader", tabList);
            }

            //add sortInfo
            if (sortInfo != null)
            {
                StringBuilder config = new StringBuilder("{");

                config.AppendFormat("field: '{0}', direction: '{1}'", sortInfo.field, sortInfo.direction);

                config.Append("}");

                desc.AddPropertyBase("sortInfo", config);
            }

            return list;
        }

        #region Public Properties

        /// <summary>   
        /// The Proxy object which provides access to a data object.
        /// </summary>
        [NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Description("The Proxy object which provides access to a data object.")]
        public List<ExtProxy> proxy { get; set; }


        /// <summary>
        /// The DataReader object which processes the data object and returns an Array of Ext.data.Record objects which are cached keyed by their id property.
        /// </summary>
        [Description("The ExtReader object which processes the data object and returns an Array of Ext.data.Record objects which are cached keyed by their id property.")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [TemplateContainer(typeof(ExtContainer))]
        [TemplateInstance(TemplateInstance.Single)]
        public List<ExtReader> reader { get; set; }

        /// <summary>
        /// An object which determines the Store sorting information.
        /// </summary>
        [NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Description("An object which determines the Store sorting information.")]
        public SortInfo sortInfo { get; set; }

        /// <summary>
        /// If passed, this store's load method is automatically called after creation with the autoLoad object.
        /// </summary>
        /// <value><c>true</c> if [auto load]; otherwise, <c>false</c>.</value>
        [Description("If passed, this store's load method is automatically called after creation with the autoLoad object.")]
        public Boolean? autoLoad { get; set; }   

        /// <summary>
        /// True if sorting is to be handled by requesting the Proxy to provide a refreshed version of the data object in sorted order, as opposed to sorting the Record cache in place (defaults to false). If remote sorting is specified, then clicking on a column header causes the current page to be requested from the server with the addition of the following two parameters: sort: String - The name (as specified in the Record's Field definition) of the field to sort on. dir : String - The direction of the sort, 'ASC' or 'DESC' (case-sensitive).
        /// </summary>
        [Description("True if sorting is to be handled by requesting the Proxy to provide a refreshed version of the data object in sorted order, as opposed to sorting the Record cache in place (defaults to false). If remote sorting is specified, then clicking on a column header causes the current page to be requested from the server with the addition of the following two parameters: sort: String - The name (as specified in the Record's Field definition) of the field to sort on. dir : String - The direction of the sort, 'ASC' or 'DESC' (case-sensitive).")]
        public Boolean? remoteSort { get; set; }

        /// <summary>
        /// True to clear all modified record information each time the store is loaded or when a record is removed. (defaults false)
        /// </summary>       
        [Description("True to clear all modified record information each time the store is loaded or when a record is removed. (defaults false")]
        public Boolean pruneModifiedRecords { get; set; }

        ///// <summary>
        ///// An object containing properties which are to be sent as parameters on any HTTP request.
        ///// </summary>
        ////[ClientConfig(JsonMode.ArrayToObject)]
        //[Description("An object containing properties which are to be sent as parameters on any HTTP request.")]
        //public Boolean baseParams { get; set; }


        #endregion
    }
}
